#include "delay.h"

/******************************Data definition array***********************************/

static u8  fac_us=0;						   
static u16 fac_ms=0;			
static u8 TaskIndex = 0;
DelayRegTable Tab;

/******************************End of Data definition array***************************/


/******************************Function declaration array*****************************/

static void BaseSysTickConfg(void);
static void SysTickRegTabInit(void);
static void SetSysTickFlg(void);
static void DelayHandle(u8 DelayTime, u8 TskName);
static void ClrSysTickTaskFlg(u8 TskType);
static   u8 GetSysTickTaskFlg(u8 TskType);

/******************************End of Function declaration array**********************/
			   
/********************************************************************
Program Function: Systick timer delay init function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

void DelayInit(void)
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	     //select the external clock
	fac_us = SystemCoreClock / 8000000;				             //system clock config  
	NVIC_SetPriority(SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);   //interrupt priority config

	fac_ms = (u16)fac_us * 1000;					             
	
	BaseSysTickConfg();                                          //clock base config
	SysTickRegTabInit();                                         //register table init
}

/********************************************************************
Program Function: System tick RegTable data init function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static void SysTickRegTabInit(void)
{
	u8 i;
	u8 *pData = (u8*)&Tab;
	
	TaskIndex = 0;
	
	for(i = 0; i < sizeof(DelayRegTable)/sizeof(u8); i++)
	{
		pData[i] = 0;
	}
}

/********************************************************************
Program Function: Task delay register function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

u8 SysTickRegTask(void)
{
	u8 Rtn = 0xFF;

	TaskIndex++;
	if(TaskIndex > SysTickTskMax)
	{
		TaskIndex = 0;
		Rtn =  0xFF;             //Register failed
	}
	else
	{
		Rtn = TaskIndex - 1;     //Register success
	}

	return Rtn;
}

/********************************************************************
Program Function: Get the SysTick task flag function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static u8 GetSysTickTaskFlg(u8 TskType)
{
	return Tab.TaskFlag[TskType];
}

/********************************************************************
Program Function: Clear the SysTick task flag function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static void ClrSysTickTaskFlg(u8 TskType)
{
	Tab.TaskFlag[TskType] = 0;
}

/********************************************************************
Program Function: Set the SysTick flag function
Program  Version: 1.0
Create      Date: 2020-10-26
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static void SetSysTickFlg(void)
{
	u8 i;
	
	for(i = 0; i < TaskIndex; i++)
	{
		Tab.TimeFlag[i] = 0x01;
	}
}

/********************************************************************
Program Function: SysTick handle callback function
Program  Version: 1.0
Create      Date: 2020-09-11
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

void SysTickHandleFunc(void (*CallBack_Func)(void), u8 TskName, u8 DelayTime)
{
	DelayHandle(DelayTime, TskName);
	
	if(NULL != CallBack_Func)
	{
		if(0x01 == (GetSysTickTaskFlg(TskName)))
		{
			(*CallBack_Func)();
			ClrSysTickTaskFlg(TskName);
		}
		else
		{
			//do nothing
		}
	}
	else
	{
		return;
	}
} 

/********************************************************************
Program Function: Delay handle function
Program  Version: 1.0
Create      Date: 2020-10-27
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static void DelayHandle(u8 DelayTime, u8 TskName)
{
	if (0x01 == Tab.TimeFlag[TskName])
	{
		Tab.TimeCunt[TskName]++;
		if (Tab.TimeCunt[TskName] >= DelayTime)   //time = DelayTime * 10ms; 
		{
			Tab.TaskFlag[TskName] = 0x01;
			Tab.TimeCunt[TskName] = 0x00;
		}
		else
		{
			//do nothing;
		}

		BaseSysTickConfg();
		Tab.TimeFlag[TskName] = 0x00;
	}
	else
	{
		//do nothing;
	}
}

/********************************************************************
Program Function: BaseSysTick config function
Program  Version: 1.0
Create      Date: 2020-10-27
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

static void BaseSysTickConfg(void)
{
	SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;   	//enable systick interrupt 
	SysTick->LOAD = (u32)fac_ms * BASE_CLOCK;		//load the time value(SysTick->LOAD is 24bit)
	SysTick->VAL = 0x00;							//clear the count
	SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;	    //start the count down
}

/********************************************************************
Program Function: Systick interrupt handle function
Program  Version: 1.0
Create      Date: 2020-10-27
Author          : Huang Cheng
Modify Instrodtn: None
********************************************************************/

void SysTick_Handler(void)
{
	SetSysTickFlg();

	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;		//stop the count down
	SysTick->VAL = 0x00;       						//clear the count
	SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; 	//disable the systick interrupt
}

/**************************@Copyright 2020 reserved by Huang Cheng**************************/
